package Util;

import Entity.Maze;
import Util.Constants.*;
/**
 * 吃豆女士的执行情况。此类包含游戏引擎和查询游戏状态所需的所有方法。
 *
 * 首先，迷宫仅在它们不可变时才加载一次。然后，游戏使用默认值初始化所有变量。
 *
 * 游戏类还提供了许多方法来提取游戏状态为字符串（用于重播以及在比赛期间通过管道进行通信）并创建副本。
 *
 * 已采取措施有效执行游戏，以确保可以快速创建副本。
 *
 * 该游戏具有一个称为advanceGame的中央更新方法，该方法对吃豆人女士采取了行动，对幽灵采取了多达4种行动。
 *
 * 然后，它更新所有角色的位置，检查是否吃了药丸或强力药丸，并相应地更新游戏状态。
 *
 * 所有其他方法都是访问游戏状态并计算众多方面，例如，给定目标所采取的方向或从a到b的最短路径。
 *
 * 从任何节点到任何其他节点的所有最短路径距离都已预先计算并从文件中加载。这使这些方法更有效。
 *
 * 关于鬼影的注意事项：鬼影不允许反转。因此，不可能简单地查找最短路径距离。取而代之的是，可以贪婪地近似此值，或使用A *正确地对其进行计算。
 *
 * 前者速度更快，错误率也较低。后者需要更长的时间，但绝对准确。
 *
 * 我们使用预先计算的最短路径距离作为可允许的启发式算法，因此它非常有效。
 * */
public class Game {
    private Maze currentMaze;
    private PacMan pacman; //TODO pacman的变化

    private void _init(int initialMaze) {
        pacman = new PacMan(currentMaze.initialPacManNodeIndex, MOVE.LEFT);
    }


    /**
     * 返回从任何节点到任何其他节点的PATH距离。
     *
     * @param fromNodeIndex
     *            the from node index
     * @param toNodeIndex
     *            the to node index
     * @return the shortest path distance
     */
    public int getShortestPathDistance(int fromNodeIndex, int toNodeIndex) {
        if (fromNodeIndex == toNodeIndex)
            return 0;
        else if (fromNodeIndex < toNodeIndex)
            return currentMaze.shortestPathDistances[((toNodeIndex * (toNodeIndex + 1)) / 2)
                    + fromNodeIndex];
        else
            return currentMaze.shortestPathDistances[((fromNodeIndex * (fromNodeIndex + 1)) / 2)
                    + toNodeIndex];
    }

    /**
     *获取可能的移动，但与提供的移动相反的移动除外。
     * @param nodeIndex
     *            The current node index
     * @param lastModeMade
     *            The last mode made (possible moves will exclude the reverse)
     * @return The set of possible moves
     */
    public MOVE[] getPossibleMoves(int nodeIndex, MOVE lastModeMade) {
        return currentMaze.graph[nodeIndex].allPossibleMoves.get(lastModeMade);
    }

    /**
     * 吃豆人当前的位置。
     *
     * @return the pacman current node index
     */
    public int getPacmanCurrentNodeIndex() {
        return pacman.currentNodeIndex;
    }

    /**
     * Current node index of Ms Pac-Man.
     *
     * @return the pacman last move made
     */
    public MOVE getPacmanLastMoveMade() {
        return pacman.lastMoveMade;
    }

}
